﻿// Author:          Achim Schnell
// Enterprise:      WTS Wassertechnik Schnell GmbH
// Copyright:       2011-2012 by WTS Wassertechnik Schnell GmbH

using System.Collections.Generic;
using System.ComponentModel;

namespace AppFx.Collections
{
	/// <summary>
	/// Represents a paged resultset.
	/// </summary>
	/// <typeparam name="T">Tye of the contained items.</typeparam>
	public class PagedEnumerable<T> : IEnumerable<T>
	{
		#region Properties

		/// <summary>
		/// The internal items-collection.
		/// </summary>
		private IEnumerable<T> Items { get; set; }

		/// <summary>
		/// Gets to max. PageSize, use .Count() to get the actual item-count.
		/// </summary>
		public int PageSize { get; private set; }

		/// <summary>
		/// The zero-based index of the page.
		/// </summary>
		public int PageIndex { get; private set; }

		/// <summary>
		/// The total amount of available pages.
		/// </summary>
		public int PageCount { get; private set; }

		/// <summary>
		/// The zero-based index of the first record in this collection.
		/// </summary>
		public int StartRecordIndex { get; private set; }

		/// <summary>
		/// The total amount of available records.
		/// </summary>
		public int TotalRecordCount { get; private set; }

		#endregion

		#region Constructors

		/// <summary>
		/// Initializes a new instance of the <see cref="PagedEnumerable&lt;T&gt;"/> class.
		/// </summary>
		/// <param name="pageSize">Size of the page.</param>
		/// <param name="pageIndex">Index of this page.</param>
		/// <param name="pageCount">The page count.</param>
		/// <param name="startRecordIndex">Start index of the record.</param>
		/// <param name="totalRecordCount">The total record count.</param>
		public PagedEnumerable(int pageSize, int pageIndex, int totalRecordCount, IEnumerable<T> items)
		{
			if (pageSize < 1)
				throw new InvalidEnumArgumentException("Parameter pageSize must be 1 greater or equal to one.");
			PageSize = pageSize;
			PageIndex = pageIndex;
			TotalRecordCount = totalRecordCount;
			Items = items;

			// Calculate the StartRecordIndex:
			StartRecordIndex = (pageIndex + 1) * pageSize;
			// Calculate PageCount:
			PageCount = (totalRecordCount + pageSize - 1) / pageSize;
		}

		#endregion

		#region IEnumerable Member

		/// <summary>
		/// Gibt einen Enumerator zurück, der die Auflistung durchläuft.
		/// </summary>
		/// <returns>
		/// Ein <see cref="T:System.Collections.Generic.IEnumerator`1"/>, der zum Durchlaufen der Auflistung verwendet werden kann.
		/// </returns>
		public IEnumerator<T> GetEnumerator()
		{
			return Items.GetEnumerator();
		}

		/// <summary>
		/// Gibt einen Enumerator zurück, der eine Auflistung durchläuft.
		/// </summary>
		/// <returns>
		/// Ein <see cref="T:System.Collections.IEnumerator"/>-Objekt, das zum Durchlaufen der Auflistung verwendet werden kann.
		/// </returns>
		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
		{
			return Items.GetEnumerator();
		}

		#endregion
	}
}
